"use client";

import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { apiGet, withAuth } from '../api/client';
import { User, updateUserApi } from '../api/auth';

type AuthState = {
  user: User | null;
  loading: boolean;
  error: string | null;
  login: (token: string) => Promise<void>;
  logout: () => void;
  refresh: () => Promise<void>;
  updateUser: (userData: Partial<User>) => Promise<void>;
};

const AuthContext = createContext<AuthState | undefined>(undefined);

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  async function fetchProfile() {
    const token = typeof window !== 'undefined' ? localStorage.getItem('accessToken') : null;
    if (!token) {
      setUser(null);
      return;
    }
    try {
      const profile = await apiGet<User>('/auth/profile', withAuth());
      setUser(profile);
      setError(null);
    } catch (err: any) {
      setUser(null);
      setError(err.message || 'Failed to get user info');
    }
  }

  useEffect(() => {
    (async () => {
      try {
        await fetchProfile();
      } finally {
        setLoading(false);
      }
    })();
  }, []);

  const value = useMemo<AuthState>(() => ({
    user,
    loading,
    error,
    login: async (token: string) => {
      localStorage.setItem('accessToken', token);
      await fetchProfile();
    },
    logout: () => {
      try {
        localStorage.clear();
      } catch {}
      setUser(null);
    },
    refresh: async () => {
      await fetchProfile();
    },
    updateUser: async (userData: Partial<User>) => {
      try {
        const updatedUser = await updateUserApi(userData);
        setUser(updatedUser);
        setError(null);
      } catch (err: any) {
        setError(err.message || 'Failed to update user info');
        throw err;
      }
    },
  }), [user, loading, error]);

  return (
    <AuthContext.Provider value={value}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error('useAuth must be used within AuthProvider');
  return ctx;
}